package com.zhj.agent.support;

import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;
import net.bytebuddy.implementation.bind.annotation.This;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;


/**
 * 方法拦截的执行器
 */
@Slf4j
public class InstMethodsInter {

    /** Interceptor */
    private InstanceMethodsAroundInterceptor interceptor;

    /**
     * Inst methods inter
     *
     * @param interceptorName interceptor name
     * @since 1.0.0
     */
    public InstMethodsInter(@NonNull Class<?> interceptorName) {
        try {
            this.interceptor = (InstanceMethodsAroundInterceptor) interceptorName.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Intercept
     *
     * @param obj          obj
     * @param allArguments all arguments
     * @param method       method
     * @param callable     callable
     * @return the object
     * @since 1.0.0
     */
    @RuntimeType
    public Object intercept(@This Object obj,
                            @AllArguments Object[] allArguments,
                            @Origin Method method,
                            @SuperCall Callable<?> callable) {
        Object result = null;
        try {
            interceptor.beforeMethod(obj, method, allArguments, method.getParameterTypes());
        } catch (Throwable throwable) {
            log.error("前置增强方法执行异常：", throwable);
        }
        try {
            result = callable.call();
        } catch (Throwable t) {
            interceptor.handleMethodException(obj, method, allArguments, method.getParameterTypes(), t);
        } finally {
            try {
                result = interceptor.afterMethod(obj, method, allArguments, method.getParameterTypes(), result);
            } catch (Throwable t) {
                log.error("后置增强方法执行异常：", t);
            }
        }
        return result;
    }

}
